package me.zhengjie.modules.serviceprovider.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.security.utils.VerifyCodeUtils;
import me.zhengjie.modules.serviceprovider.domain.TServiceproviderInfo;
import me.zhengjie.modules.serviceprovider.domain.TServiceproviderManager;
import me.zhengjie.modules.serviceprovider.repository.TServiceproviderManagerRepository;
import me.zhengjie.modules.serviceprovider.repository.TServiceproviderPersonRepository;
import me.zhengjie.modules.serviceprovider.service.TServiceproviderManagerService;
import me.zhengjie.modules.serviceprovider.service.dto.*;
import me.zhengjie.modules.system.service.DictDetailService;
import me.zhengjie.modules.system.service.dto.DictDetailDTO;
import me.zhengjie.modules.workorder.repository.TWorkOrderRepository;
import me.zhengjie.service.SmsSerivice;
import me.zhengjie.utils.*;
import me.zhengjie.modules.serviceprovider.repository.TServiceproviderInfoRepository;
import me.zhengjie.modules.serviceprovider.service.TServiceproviderInfoService;
import me.zhengjie.modules.serviceprovider.service.mapper.TServiceproviderInfoMapper;
import org.apache.poi.hssf.extractor.ExcelExtractor;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

/**
* @author xuyukun
* @date 2019-07-20
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class TServiceproviderInfoServiceImpl implements TServiceproviderInfoService {

    @Autowired
    private TServiceproviderInfoRepository tServiceproviderInfoRepository;
    @Autowired
    private DictDetailService dictDetailService;
    @Autowired
    private TServiceproviderInfoMapper tServiceproviderInfoMapper;
    @Autowired
    private TWorkOrderRepository tWorkOrderRepository;
    @Autowired
    private TServiceproviderManagerService tServiceproviderManagerService;
    @Autowired
    private SmsSerivice smsSerivice;
    @Autowired
    private TServiceproviderManagerRepository tServiceproviderManagerRepository;
    @Autowired
    private TServiceproviderPersonRepository tServiceproviderPersonRepository;

    @Override
    public Object queryAll(TServiceproviderInfoQueryCriteria criteria, Pageable pageable){
        Page<TServiceproviderInfo> page = tServiceproviderInfoRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        Iterator<TServiceproviderInfo> tServiceproviderInfos=page.iterator();
        while (tServiceproviderInfos.hasNext()) {
            TServiceproviderInfo tServiceproviderInfo = tServiceproviderInfos.next();
            if(tServiceproviderInfo.getSeproId()!=null){
                DictDetailDTO dictDetailDTO= dictDetailService.findById(tServiceproviderInfo.getSeproId());
                if(dictDetailDTO!=null){
                    tServiceproviderInfo.setSeproItemName(dictDetailDTO.getLabel());

                }
            }
            if(tServiceproviderInfo.getCompanyItemId()!=null){
                DictDetailDTO dictDetailDTO= dictDetailService.findById(tServiceproviderInfo.getCompanyItemId());
                if(dictDetailDTO!=null){
                    tServiceproviderInfo.setCompanyItemName(dictDetailDTO.getLabel());

                }
            }
        }
        return PageUtil.toPage(page.map(tServiceproviderInfoMapper::toDto));
    }

    @Override
    public XSSFWorkbook exportEvaluate(TServiceproviderInfoQueryCriteria criteria) {
        try {
            if (StringUtils.isEmpty(criteria.getStartTime())) {
                criteria.setStartTime("2021-01-01");
            }
            if (StringUtils.isEmpty(criteria.getEndTime())) {
                criteria.setEndTime(DateUtil.parseDateToStr(new Date(), "yyyy-MM-dd") + " 23:59:59");
            } else {
                criteria.setEndTime(criteria.getEndTime() + " 23:59:59");
            }

            List<Object[]> evaluates = tServiceproviderInfoRepository.queryAllProviderEvaluates(criteria.getRefeName(), criteria.getStartTime(),
                    criteria.getEndTime());
            XSSFWorkbook wb = new XSSFWorkbook(this.getClass().getResourceAsStream("/evaluate.xlsx"));
            //创建表头等
            XSSFSheet sheet = wb.getSheetAt(0);
            //wb.setSheetName(0, "供应商评价");
            //创建行
            Integer flag = 2;
            if(evaluates.size() > 0) {
                sheet.shiftRows(flag, flag+evaluates.size(), evaluates.size(), true, false);
                for(int i = 0; i < evaluates.size(); i++) {
                    XSSFRow row = sheet.createRow(flag+i);
                    Object[] record = evaluates.get(i);
                    row.createCell(0).setCellValue((String)record[0]);
                    row.createCell(1).setCellValue(((BigInteger)record[1]).toString());
                    row.createCell(2).setCellValue(((BigInteger)record[2]).toString());
                    row.createCell(3).setCellValue(((BigDecimal)record[3]).toString());
                    row.createCell(4).setCellValue(((BigDecimal)record[4]).toString());
                    row.createCell(5).setCellValue(((BigDecimal)record[5]).toString());
                    row.createCell(6).setCellValue(((BigDecimal)record[6]).toString());
                    row.createCell(7).setCellValue(((Double)record[7]).toString());
                    row.createCell(8).setCellValue(((Double)record[8]).toString());
                    row.createCell(9).setCellValue(((BigDecimal)record[9]).toString());
                    row.createCell(10).setCellValue(((BigDecimal)record[10]).toString());
                    row.createCell(11).setCellValue(((BigDecimal)record[11]).toString());
                    row.createCell(12).setCellValue(((BigDecimal)record[12]).toString());
                    row.createCell(13).setCellValue(((BigDecimal)record[13]).toString());
                    row.createCell(14).setCellValue(((BigDecimal)record[14]).toString());
                }
            }
            return wb;
        }catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    @Override
	public Object queryProviderEvaluates(TServiceproviderInfoQueryCriteria criteria, Pageable pageable) {
        if(StringUtils.isEmpty(criteria.getStartTime())) {
            criteria.setStartTime("2021-01-01");
        }
        if(StringUtils.isEmpty(criteria.getEndTime())) {
            criteria.setEndTime(DateUtil.parseDateToStr(new Date(),"yyyy-MM-dd") + " 23:59:59");
        } else {
            criteria.setEndTime(criteria.getEndTime() + " 23:59:59");
        }
        //
    	Page<Object[]> page = tServiceproviderInfoRepository.queryProviderEvaluates(criteria.getRefeName(),criteria.getStartTime(),
    			criteria.getEndTime(),pageable);
        JSONArray array = new JSONArray();
        if(page.getContent() != null && page.getContent().size() > 0) {
            for(Object[] value:  page.getContent()) {
                JSONObject obj = new JSONObject();
                obj.put("name", (String)value[0]);
                obj.put("reciveCount",value[1]);
                obj.put("finishCount",value[2]);
                obj.put("refuseCount",value[3]);
                obj.put("returnCount",value[4]);
                obj.put("timeOutCount",value[5]);
                obj.put("unArriveCount",value[6]);
                obj.put("sumTime",value[7]);
                obj.put("acSumTime",value[8]);
                obj.put("unOkCount",value[9]);
                obj.put("justOkCount",value[10]);
                obj.put("okCount",value[11]);
                obj.put("levelACount",value[12]);
                obj.put("levelBCount",value[13]);
                obj.put("levelCCount",value[14]);

                array.add(obj);
            }
        }
		return PageUtil.toPageWithContent(page,array);
	}

    @Override
    public Object queryAll(TServiceproviderInfoQueryCriteria criteria){
        return tServiceproviderInfoMapper.toDto(tServiceproviderInfoRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    public TServiceproviderInfoDTO findById(Long id) {
        Optional<TServiceproviderInfo> tServiceproviderInfo = tServiceproviderInfoRepository.findById(id);
        ValidationUtil.isNull(tServiceproviderInfo,"TServiceproviderInfo","id",id);
        return tServiceproviderInfoMapper.toDto(tServiceproviderInfo.get());
    }

    @Override
    public TServiceproviderInfoDTO findByInviteCode(String inviteCode) {
        Optional<TServiceproviderInfo> tServiceproviderInfo = tServiceproviderInfoRepository.findByInviteCode(inviteCode);
        ValidationUtil.isNull(tServiceproviderInfo,"TServiceproviderInfo","inviteCode",inviteCode);
        return tServiceproviderInfoMapper.toDto(tServiceproviderInfo.get());
    }

    @Override
    public TServiceproviderInfoDTO findBySeproCode(String code) {
        Optional<TServiceproviderInfo> optional = tServiceproviderInfoRepository.findBySeproCode(code);
        if(optional.isPresent()) {
            return tServiceproviderInfoMapper.toDto(optional.get());
        } else {
            return null;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TServiceproviderInfoDTO create(TServiceproviderInfo resources) {
        Optional<TServiceproviderInfo> optional = tServiceproviderInfoRepository.findBySeproCode(resources.getSeproCode());
        if(optional.isPresent()) {
            throw new BadRequestException("企业信用代码已存在");
        }

        //默认邀请码
        String inviteCode = VerifyCodeUtils.generateInviteCode(8);
        Optional<TServiceproviderInfo> optionalTServiceproviderInfoOptional = tServiceproviderInfoRepository.findByInviteCode(inviteCode);
        while(optionalTServiceproviderInfoOptional.isPresent()) {
            optionalTServiceproviderInfoOptional = tServiceproviderInfoRepository.findByInviteCode(inviteCode);
        }
        resources.setInviteCode(inviteCode);

        return tServiceproviderInfoMapper.toDto(tServiceproviderInfoRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(TServiceproviderInfo resources) {
        Optional<TServiceproviderInfo> optionalTServiceproviderInfo = tServiceproviderInfoRepository.findById(resources.getId());
        ValidationUtil.isNull( optionalTServiceproviderInfo,"TServiceproviderInfo","id",resources.getId());

        TServiceproviderInfo tServiceproviderInfo = optionalTServiceproviderInfo.get();
        boolean flag = false;
        if(!resources.getSeproName().equals(tServiceproviderInfo.getSeproName())) {
            flag = true;
        }

        Optional<TServiceproviderInfo> optional = tServiceproviderInfoRepository.findBySeproCode(resources.getSeproCode());
        if(optional.isPresent() && !optional.get().getId().equals(resources.getId())) {
            throw new BadRequestException("企业信用代码已存在");
        }

        // 此处需自己修改
        resources.setId(tServiceproviderInfo.getId());
        tServiceproviderInfo.setInviteCode(tServiceproviderInfo.getInviteCode());  //邀请码只能通过重置

        tServiceproviderInfoRepository.save(resources);

        if(flag) {
            tWorkOrderRepository.updateSupplierName(resources.getId(), resources.getSeproName());
            tServiceproviderManagerRepository.updateSupplierName(resources.getId(), resources.getSeproName());
            tServiceproviderPersonRepository.updateSupplierName(resources.getId(), resources.getSeproName());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        tServiceproviderInfoRepository.deleteById(id);
    }


    @Override
    public List<Object[]> queryServiceproviderInfo(String major, ArrayList<String> level, String country, String province, String city, String county) {
        return tServiceproviderInfoRepository.queryServiceproviderInfo(major,level,country,province,city,county);
    }

    @Override
    public void verify(Long id, Integer state, String reason,Long seproId) {
        Optional<TServiceproviderInfo> optionalTServiceproviderInfo = tServiceproviderInfoRepository.findById(id);
        ValidationUtil.isNull( optionalTServiceproviderInfo,"TServiceproviderInfo","id", id);

        TServiceproviderInfo tServiceproviderInfo = optionalTServiceproviderInfo.get();
        tServiceproviderInfo.setState(Long.valueOf(state));
        if(seproId > 0) {  //分类
            tServiceproviderInfo.setSeproId(seproId);
        }
        if(!state.equals(1)) { //审核不通过
            tServiceproviderInfo.setReason(reason);
        }

        TServiceproviderManagerQueryCriteria query = new TServiceproviderManagerQueryCriteria();
        query.setIsManager(1);
        query.setServiceproviderId(tServiceproviderInfo.getId());
        List<TServiceproviderManagerDTO> managerList = (List<TServiceproviderManagerDTO>)tServiceproviderManagerService.queryAll(query);
        TServiceproviderManagerDTO managerDTO = managerList.get(0);

        //更新状态
        tServiceproviderInfoRepository.save(tServiceproviderInfo);

        //发送短信
        String pass = state ==1 ? "通过" : "不通过";
        String reasonString = state== 1 ? String.format("账号:%s,初始密码:%s", managerDTO.getUsername(), "123456") :
                reason;
        smsSerivice.sendAuditSms(managerDTO.getCellphone(), pass, reasonString);
    }

    /**
     * 重置,改为后台随机生成
     * @param id
     * @param _inviteCode
     */
    @Override
    public String resetInviteCode(Long id, String _inviteCode) {
        Optional<TServiceproviderInfo> optionalTServiceproviderInfo = tServiceproviderInfoRepository.findById(id);
        ValidationUtil.isNull( optionalTServiceproviderInfo,"TServiceproviderInfo","id", id);

        String inviteCode = VerifyCodeUtils.generateInviteCode(8);
        Optional<TServiceproviderInfo> optionalTServiceproviderInfoOptional = tServiceproviderInfoRepository.findByInviteCode(inviteCode);
        while(optionalTServiceproviderInfoOptional.isPresent()) {
            optionalTServiceproviderInfoOptional = tServiceproviderInfoRepository.findByInviteCode(inviteCode);
        }

        TServiceproviderInfo tServiceproviderInfo = optionalTServiceproviderInfo.get();
        tServiceproviderInfo.setInviteCode(inviteCode);
        tServiceproviderInfoRepository.save(tServiceproviderInfo);

        return inviteCode ;
    }


}